home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / M_smallmech.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-12-21  |  8.9 KB  |  384 lines

  1. /*
  2. ==============================================================================
  3.  
  4. Small Mech
  5.  
  6. ==============================================================================
  7. */
  8.  
  9. #include "g_local.h"
  10. #include "M_smallmech.h"
  11.  
  12.  
  13. void smallmech_doattack_rocket (edict_t *self);
  14.  
  15. static int    sound_pain;
  16. static int    sound_idle;
  17. static int    sound_step;
  18. static int    sound_sight;
  19. static int    sound_windup;
  20. static int    sound_shoot;
  21.  
  22. //
  23. // misc
  24. //
  25.  
  26. void smallmech_sight (edict_t *self, edict_t *other)
  27. {
  28.     gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
  29. }
  30.  
  31.  
  32. void smallmech_footstep (edict_t *self)
  33. {
  34.     gi.sound (self, CHAN_BODY, sound_step, 1, ATTN_NORM, 0);
  35. }
  36.  
  37. void smallmech_windup (edict_t *self)
  38. {
  39.     gi.sound (self, CHAN_WEAPON, sound_windup, 1, ATTN_NORM, 0);
  40. }
  41.  
  42. void smallmech_idle (edict_t *self)
  43. {
  44.     gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
  45. }
  46.  
  47.  
  48. //
  49. // stand
  50. //
  51.  
  52. mframe_t smallmech_frames_stand []=
  53. {
  54.     
  55.     ai_stand, 0, smallmech_idle,
  56.     ai_stand, 0, NULL,
  57.     ai_stand, 0, NULL,
  58.     ai_stand, 0, NULL,
  59.     ai_stand, 0, NULL,
  60.     ai_stand, 0, NULL,
  61.     ai_stand, 0, NULL,
  62.     ai_stand, 0, smallmech_idle,
  63.     ai_stand, 0, NULL,
  64.     ai_stand, 0, NULL,
  65.     ai_stand, 0, NULL,
  66.     ai_stand, 0, NULL,
  67.     ai_stand, 0, NULL
  68. };
  69. mmove_t    smallmech_move_stand = {FRAME_idle01, FRAME_idle13, smallmech_frames_stand, NULL};
  70.     
  71. void smallmech_stand (edict_t *self)
  72. {
  73.     self->monsterinfo.currentmove = &smallmech_move_stand;
  74. }
  75.  
  76.  
  77. //
  78. // walk
  79. //
  80.  
  81. void smallmech_walk (edict_t *self);
  82.  
  83.  
  84. mframe_t smallmech_frames_walk [] =
  85. {
  86.     ai_run, 35, NULL,
  87.     ai_run, 25, NULL,
  88.     ai_run, 15, smallmech_footstep,
  89.     ai_run, 12,  NULL,
  90.     ai_run, 5,  NULL,
  91.     ai_run, 11,  NULL,
  92.     ai_run, 34, NULL,
  93.     ai_run, 26, NULL,
  94.     ai_run, 16, smallmech_footstep,
  95.     ai_run, 14,  NULL,
  96.     ai_run, 7,  NULL,
  97.     ai_run, 11,  NULL
  98. };
  99. mmove_t    smallmech_move_walk = {FRAME_walk01, FRAME_walk12, smallmech_frames_walk, NULL};
  100.  
  101. void smallmech_walk (edict_t *self)
  102. {
  103.     self->monsterinfo.currentmove = &smallmech_move_walk;
  104. }
  105.  
  106.  
  107. //
  108. // run
  109. //
  110.  
  111. void smallmech_run (edict_t *self);
  112.  
  113. mframe_t smallmech_frames_run [] =
  114. {
  115.     ai_run, 35, NULL,
  116.     ai_run, 25, NULL,
  117.     ai_run, 15, smallmech_footstep,
  118.     ai_run, 12,  NULL,
  119.     ai_run, 5,  NULL,
  120.     ai_run, 11,  NULL,
  121.     ai_run, 34, NULL,
  122.     ai_run, 26, NULL,
  123.     ai_run, 16, smallmech_footstep,
  124.     ai_run, 14,  NULL,
  125.     ai_run, 7,  NULL,
  126.     ai_run, 11,  NULL
  127. };
  128. mmove_t    smallmech_move_run = {FRAME_walk01, FRAME_walk12, smallmech_frames_run, NULL};
  129.  
  130. void smallmech_run (edict_t *self)
  131. {
  132.     if (self->enemy && self->enemy->client)
  133.         self->monsterinfo.aiflags |= AI_BRUTAL;
  134.     else
  135.         self->monsterinfo.aiflags &= ~AI_BRUTAL;
  136.  
  137.     if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  138.     {
  139.         self->monsterinfo.currentmove = &smallmech_move_stand;
  140.         return;
  141.     }
  142.  
  143.     self->monsterinfo.currentmove = &smallmech_move_run;
  144.     
  145. }
  146.  
  147. //
  148. // pain
  149. //
  150.  
  151. mframe_t smallmech_frames_pain1 [] =
  152. {
  153.     ai_move, 0, NULL,
  154.     ai_move, 0, NULL,
  155.     ai_move, 0, NULL,
  156.     ai_move, 0, NULL,
  157.     ai_move, 0, NULL,
  158.     ai_move, 0, NULL,
  159.     ai_move, 0, NULL
  160. };
  161. mmove_t smallmech_move_pain1 = {FRAME_pain01, FRAME_pain07, smallmech_frames_pain1, smallmech_run};
  162.  
  163. void smallmech_pain (edict_t *self, edict_t *other, float kick, int damage)
  164. {
  165.     if (self->health < (self->max_health / 2))
  166.             self->s.skinnum |= 1;
  167.  
  168.     if (damage <= 10)
  169.         return;
  170.  
  171.     if (level.time < self->pain_debounce_time)
  172.             return;
  173.  
  174.     if (damage <= 30)
  175.         if (random() > 0.2)
  176.             return;
  177.  
  178.     self->pain_debounce_time = level.time + 3;
  179.     gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
  180.  
  181.     self->monsterinfo.currentmove = &smallmech_move_pain1;
  182. }
  183.  
  184.  
  185. //
  186. // attacks
  187. //
  188. void robotBlaster (edict_t *self)
  189. {
  190.     vec3_t    forward, right;
  191.     vec3_t    start;
  192.     vec3_t    end;
  193.     vec3_t    dir;
  194.     int        flash_number;
  195.  
  196.     
  197.     flash_number = MZ2_TANK_BLASTER_3;
  198.  
  199.     AngleVectors (self->s.angles, forward, right, NULL);
  200.     right[0] = right[0] * 0.0;
  201.     right[1] = right[1] * 0.0;
  202.     G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
  203.  
  204.     VectorCopy (self->enemy->s.origin, end);
  205.     end[2] += self->enemy->viewheight;
  206.     VectorSubtract (end, start, dir);
  207.     gi.sound (self, CHAN_VOICE, sound_shoot, 1, ATTN_NORM, 0);
  208.     monster_fire_blaster (self, start, dir, 15, 800, flash_number, EF_BLASTER);
  209. }    
  210.  
  211. void smallmechRocket (edict_t *self)
  212. {
  213.     vec3_t    forward, right;
  214.     vec3_t    start;
  215.     vec3_t    dir;
  216.     vec3_t    vec;
  217.     vec3_t  temp;
  218.     int        flash_number;
  219.  
  220.     if (self->s.frame == FRAME_shoot11)
  221.         flash_number = MZ2_TANK_ROCKET_1;
  222.     else if (self->s.frame == FRAME_shoot11)
  223.         flash_number = MZ2_TANK_ROCKET_2;
  224.     else // (self->s.frame == FRAME_attak330)
  225.         flash_number = MZ2_TANK_ROCKET_3;
  226.  
  227.     AngleVectors (self->s.angles, forward, right, NULL);
  228.     right[0] = right[0] * 0.0;
  229.     right[1] = right[1] * 0.0;
  230.     VectorCopy (self->s.origin, temp);
  231.     temp[2] = temp[2] - 22;
  232.     G_ProjectSource (temp, monster_flash_offset[flash_number], forward, right, start);
  233.  
  234.     VectorCopy (self->enemy->s.origin, vec);
  235.     vec[2] += self->enemy->viewheight;
  236.     VectorSubtract (vec, start, dir);
  237.     VectorNormalize (dir);
  238.  
  239.     monster_fire_sidewinder (self, start, dir, 30, 250, flash_number);
  240. }    
  241.  
  242. mframe_t smallmech_frames_attack_fire_blaster [] =
  243. {
  244.     ai_charge, -3, smallmech_windup,    // Loop Start    22 
  245.     ai_charge, 0,  NULL,
  246.     ai_charge, 0,  NULL,
  247.     ai_charge, 0,  NULL,
  248.     ai_charge, -3, NULL,                // Loop Start    22 
  249.     ai_charge, 0,  NULL,
  250.     ai_charge, 0,  NULL,
  251.     ai_charge, 0,  NULL,
  252.     ai_charge, 0,  NULL,
  253.     ai_charge, 0,  NULL,
  254.     ai_charge, 0,  robotBlaster,
  255.     ai_charge, 0,  NULL,
  256.     ai_charge, -3, NULL,                // Loop Start    22 
  257.     ai_charge, 0,  NULL,
  258.     ai_charge, 0,  NULL,
  259.     ai_charge, 0,  NULL,
  260.     ai_charge, -1, NULL                    // 30    Loop End
  261. };
  262. mmove_t smallmech_move_attack_fire_blaster = {FRAME_shoot01, FRAME_shoot17, smallmech_frames_attack_fire_blaster, smallmech_run};
  263.  
  264. mframe_t smallmech_frames_attack_fire_rocket [] =
  265. {
  266.     ai_charge, -3, smallmech_windup,    // Loop Start    22 
  267.     ai_charge, 0,  NULL,
  268.     ai_charge, 0,  NULL,
  269.     ai_charge, 0,  NULL,
  270.     ai_charge, -3, NULL,                // Loop Start    22 
  271.     ai_charge, 0,  NULL,
  272.     ai_charge, 0,  NULL,
  273.     ai_charge, 0,  NULL,
  274.     ai_charge, 0,  NULL,
  275.     ai_charge, 0,  NULL,
  276.     ai_charge, 0,  smallmechRocket,
  277.     ai_charge, 0,  NULL,
  278.     ai_charge, -3, NULL,                // Loop Start    22 
  279.     ai_charge, 0,  NULL,
  280.     ai_charge, 0,  NULL,
  281.     ai_charge, 0,  NULL,
  282.     ai_charge, -1, NULL                    // 30    Loop End
  283. };
  284. mmove_t smallmech_move_attack_fire_rocket = {FRAME_shoot01, FRAME_shoot17, smallmech_frames_attack_fire_rocket, smallmech_run};
  285.  
  286. void smallmech_doattack_rocket (edict_t *self)
  287. {
  288.     self->monsterinfo.currentmove = &smallmech_move_attack_fire_rocket;
  289. }
  290.  
  291. void smallmech_attack(edict_t *self)
  292. {
  293.     vec3_t    vec;
  294.     float    range;
  295.  
  296.     VectorSubtract (self->enemy->s.origin, self->s.origin, vec);
  297.     range = VectorLength (vec);
  298.  
  299.     if (random() < 0.5)
  300.         self->monsterinfo.currentmove = &smallmech_move_attack_fire_blaster;
  301.     else
  302.         self->monsterinfo.currentmove = &smallmech_move_attack_fire_rocket;
  303.         
  304.     self->pain_debounce_time = level.time + 5.0;    // no pain for a while
  305. }
  306.  
  307.  
  308. //
  309. // death
  310. //
  311.  
  312. void smallmech_dead (edict_t *self)
  313. {
  314.     VectorSet (self->mins, -16, -16, -16);
  315.     VectorSet (self->maxs, 16, 16, 24);
  316.     self->movetype = MOVETYPE_TOSS;
  317.     self->svflags |= SVF_DEADMONSTER;
  318.     self->nextthink = 0;
  319.     gi.linkentity (self);
  320. }
  321.  
  322.  
  323. void smallmech_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
  324. {
  325.     BecomeExplosion1(self);
  326.     self->deadflag = DEAD_DEAD;
  327. }
  328.  
  329.  
  330. //
  331. // monster_smallmech
  332. //
  333.  
  334. /*QUAKED monster_smallmech (1 .5 0) (-32 -32 -16) (32 32 72) Ambush Trigger_Spawn Sight
  335. */
  336. /*QUAKED monster_smallmech_commander (1 .5 0) (-32 -32 -16) (32 32 72) Ambush Trigger_Spawn Sight
  337. */
  338. void SP_monster_smallmech (edict_t *self)
  339. {
  340.     if (deathmatch->value)
  341.     {
  342.         G_FreeEdict (self);
  343.         return;
  344.     }
  345.  
  346.     self->s.modelindex = gi.modelindex ("models/monsters/smallmech/tris.md2");
  347.     VectorSet (self->mins, -16, -16, -40);
  348.     VectorSet (self->maxs, 16, 16, 24);
  349.     self->movetype = MOVETYPE_STEP;
  350.     self->solid = SOLID_BBOX;
  351.  
  352.     sound_pain = gi.soundindex ("smallmech/pain.wav");
  353.     sound_idle = gi.soundindex ("smallmech/idle.wav");
  354.     sound_step = gi.soundindex ("smallmech/step.wav");
  355.     sound_windup = gi.soundindex ("smallmech_windup.wav");
  356.     sound_sight = gi.soundindex ("smallmech/sight.wav");
  357.     sound_shoot = gi.soundindex ("smallmech/laser.wav");
  358.  
  359.     self->max_health = 150;
  360.     self->health = self->max_health;
  361.     self->gib_health = -200;
  362.     self->classname = "monster_mech";
  363.     
  364.     self->mass = 500;
  365.  
  366.     self->pain = smallmech_pain;
  367.     self->die = smallmech_die;
  368.     self->monsterinfo.stand = smallmech_stand;
  369.     self->monsterinfo.walk = smallmech_walk;
  370.     self->monsterinfo.run = smallmech_run;
  371.     self->monsterinfo.dodge = NULL;
  372.     self->monsterinfo.attack = smallmech_attack;
  373.     self->monsterinfo.melee = NULL;
  374.     self->monsterinfo.sight = smallmech_sight;
  375.     self->monsterinfo.idle = smallmech_idle;
  376.  
  377.     gi.linkentity (self);
  378.     
  379.     self->monsterinfo.currentmove = &smallmech_move_stand;
  380.     self->monsterinfo.scale = MODEL_SCALE;
  381.  
  382.     walkmonster_start(self);
  383. }
  384.